4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
16 namespace Microsoft
.JScript
.Vsa
{
18 using Microsoft
.JScript
;
21 using System
.Collections
;
23 using System
.Globalization
;
24 using System
.Reflection
;
25 using System
.Reflection
.Emit
;
26 using System
.Resources
;
28 using System
.Threading
;
30 using System
.Runtime
.Remoting
.Messaging
;
31 using System
.Security
;
32 using System
.Security
.Cryptography
;
33 using System
.Security
.Permissions
;
34 using System
.Runtime
.InteropServices
;
37 internal enum LoaderAPI
{
40 ReflectionOnlyLoadFrom
44 [GuidAttribute("B71E484D-93ED-4b56-BFB9-CEED5134822B")]
46 [Obsolete(VsaObsolete
.Description
)]
47 public sealed class VsaEngine
: BaseVsaEngine
, IEngine2
, IRedirectOutput
{
48 internal bool alwaysGenerateIL
;
50 private Hashtable Defines
;
53 internal bool doPrint
;
54 internal bool doSaveAfterCompile
;
55 private bool doWarnAsError
;
56 private int nWarningLevel
;
57 internal bool genStartupClass
;
58 internal bool isCLSCompliant
;
59 internal bool versionSafe
;
60 private String PEFileName
;
61 internal PEFileKinds PEFileKind
;
62 internal PortableExecutableKinds PEKindFlags
;
63 internal ImageFileMachine PEMachineArchitecture
;
64 internal LoaderAPI ReferenceLoaderAPI
;
65 private Version versionInfo
;
67 private CultureInfo errorCultureInfo
;
70 //In appdomain used to executing JScript debugger expression evaluator
71 static internal bool executeForJSEE
= false;
73 private String libpath
;
74 private String
[] libpathList
;
76 private bool isCompilerSet
;
78 internal VsaScriptScope globalScope
;
79 private ArrayList packages
;
80 private ArrayList scopes
;
81 private ArrayList implicitAssemblies
;
82 private SimpleHashtable implicitAssemblyCache
;
83 private ICollection managedResources
;
84 private string debugDirectory
;
85 private string tempDirectory
;
86 private RNGCryptoServiceProvider randomNumberGenerator
;
88 private byte[] rawPDB
;
89 internal int classCounter
;
91 private SimpleHashtable cachedTypeLookups
;
93 internal Thread runningThread
;
94 private CompilerGlobals compilerGlobals
;
95 private Globals globals
;
97 // Used only during VsaEngine.Compile. It is reset at the beginning of the
98 // function. It is incremented as errors are reported via OnCompilerError.
99 private int numberOfErrors
;
101 private String runtimeDirectory
;
102 private static readonly Version CurrentProjectVersion
= new Version("1.0");
104 private Hashtable typenameTable
; // for checking CLS compliance
106 private static string engineVersion
= GetVersionString();
107 private static string GetVersionString(){
108 return BuildVersionInfo
.MajorVersion
109 + "." + BuildVersionInfo
.MinorVersion
.ToString(CultureInfo
.InvariantCulture
).PadLeft(2, '0')
110 + "." + BuildVersionInfo
.Revision
.ToString(CultureInfo
.InvariantCulture
)
111 + "." + BuildVersionInfo
.Build
.ToString(CultureInfo
.InvariantCulture
).PadLeft(4, '0');
119 public VsaEngine(bool fast
) : base("JScript", VsaEngine
.engineVersion
, true){
120 this.alwaysGenerateIL
= false;
121 this.autoRef
= false;
124 this.genDebugInfo
= false;
125 this.genStartupClass
= true;
126 this.doPrint
= false;
127 this.doWarnAsError
= false;
128 this.nWarningLevel
= 4;
129 this.isCLSCompliant
= false;
130 this.versionSafe
= false;
131 this.PEFileName
= null;
132 this.PEFileKind
= PEFileKinds
.Dll
;
133 this.PEKindFlags
= PortableExecutableKinds
.ILOnly
;
134 this.PEMachineArchitecture
= ImageFileMachine
.I386
;
135 this.ReferenceLoaderAPI
= LoaderAPI
.LoadFrom
;
136 this.errorCultureInfo
= null;
138 this.libpathList
= null;
140 this.globalScope
= null;
141 this.vsaItems
= new VsaItems(this);
142 this.packages
= null;
144 this.classCounter
= 0;
145 this.implicitAssemblies
= null;
146 this.implicitAssemblyCache
= null;
147 this.cachedTypeLookups
= null;
149 this.isEngineRunning
= false;
150 this.isEngineCompiled
= false;
151 this.isCompilerSet
= false;
152 this.isClosed
= false;
154 this.runningThread
= null;
155 this.compilerGlobals
= null;
157 this.runtimeDirectory
= null;
158 Globals
.contextEngine
= this;
159 this.runtimeAssembly
= null;
160 this.typenameTable
= null;
163 private Assembly runtimeAssembly
;
164 private static Hashtable assemblyReferencesTable
= null;
165 // This constructor is called at run time to instantiate an engine for a given assembly
166 private VsaEngine(Assembly runtimeAssembly
) : this(true){
167 this.runtimeAssembly
= runtimeAssembly
;
170 private static Module reflectionOnlyVsaModule
= null;
171 private static Module reflectionOnlyJScriptModule
= null;
173 internal void EnsureReflectionOnlyModulesLoaded() {
174 if (VsaEngine
.reflectionOnlyVsaModule
== null) {
175 VsaEngine
.reflectionOnlyVsaModule
= Assembly
.ReflectionOnlyLoadFrom(typeof(IVsaEngine
).Assembly
.Location
).GetModule("Microsoft.Vsa.dll");
176 VsaEngine
.reflectionOnlyJScriptModule
= Assembly
.ReflectionOnlyLoadFrom(typeof(VsaEngine
).Assembly
.Location
).GetModule("Microsoft.JScript.dll");
180 internal Module VsaModule
{
182 if (this.ReferenceLoaderAPI
!= LoaderAPI
.ReflectionOnlyLoadFrom
)
183 return typeof(IVsaEngine
).Module
;
184 EnsureReflectionOnlyModulesLoaded();
185 return VsaEngine
.reflectionOnlyVsaModule
;
189 internal Module JScriptModule
{
191 if (this.ReferenceLoaderAPI
!= LoaderAPI
.ReflectionOnlyLoadFrom
)
192 return typeof(VsaEngine
).Module
;
193 EnsureReflectionOnlyModulesLoaded();
194 return VsaEngine
.reflectionOnlyJScriptModule
;
198 private void AddChildAndValue(XmlDocument doc
, XmlElement parent
, string name
, string value){
199 XmlElement option
= doc
.CreateElement(name
);
200 this.CreateAttribute(doc
, option
, "Value", value);
201 parent
.AppendChild(option
);
204 internal void AddPackage(PackageScope pscope
){
205 if (this.packages
== null)
206 this.packages
= new ArrayList(8);
207 IEnumerator e
= this.packages
.GetEnumerator();
208 while (e
.MoveNext()){
209 PackageScope cps
= (PackageScope
)e
.Current
;
210 if (cps
.name
.Equals(pscope
.name
)){
211 cps
.owner
.MergeWith(pscope
.owner
);
215 this.packages
.Add(pscope
);
218 internal void CheckForErrors(){
219 if (!this.isClosed
&& !this.isEngineCompiled
){
220 SetUpCompilerEnvironment();
221 Globals
.ScopeStack
.Push(this.GetGlobalScope().GetObject());
223 foreach (Object item
in this.vsaItems
){
224 if (item
is VsaReference
)
225 ((VsaReference
)item
).Compile(); //Load the assembly into memory.
227 if (this.vsaItems
.Count
> 0)
228 this.SetEnclosingContext(new WrappedNamespace("", this)); //Provide a way to find types that are not inside of a name space
229 foreach (Object item
in this.vsaItems
){
230 if (!(item
is VsaReference
))
231 ((VsaItem
)item
).CheckForErrors();
233 if (null != this.globalScope
)
234 this.globalScope
.CheckForErrors(); //In case the host added items to the global scope.
236 Globals
.ScopeStack
.Pop();
239 this.globalScope
= null;
242 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
243 public IVsaEngine
Clone(AppDomain domain
){
244 throw new NotImplementedException();
247 // See security comment at BaseVsa.Run()
248 [PermissionSet(SecurityAction
.Demand
, Name
="FullTrust")]
249 public bool CompileEmpty(){
250 this.TryObtainLock();
252 return this.DoCompile();
258 private void CreateAttribute(XmlDocument doc
, XmlElement elem
, string name
, string value){
259 XmlAttribute attribute
= doc
.CreateAttribute(name
);
260 elem
.SetAttributeNode(attribute
);
261 elem
.SetAttribute(name
, value);
264 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
265 public void ConnectEvents(){
268 internal CompilerGlobals CompilerGlobals
{
270 if (this.compilerGlobals
== null)
271 this.compilerGlobals
= new CompilerGlobals(this, this.Name
, this.PEFileName
, this.PEFileKind
,
272 this.doSaveAfterCompile
|| this.genStartupClass
, !this.doSaveAfterCompile
|| this.genStartupClass
, this.genDebugInfo
, this.isCLSCompliant
,
273 this.versionInfo
, this.globals
);
274 return this.compilerGlobals
;
279 private static TypeReferences _reflectionOnlyTypeRefs
;
280 private TypeReferences TypeRefs
{
282 TypeReferences typeRefs
;
283 if (LoaderAPI
.ReflectionOnlyLoadFrom
== this.ReferenceLoaderAPI
) {
284 typeRefs
= VsaEngine
._reflectionOnlyTypeRefs
;
285 if (null == typeRefs
)
286 typeRefs
= VsaEngine
._reflectionOnlyTypeRefs
= new TypeReferences(this.JScriptModule
);
288 typeRefs
= Runtime
.TypeRefs
;
293 public static GlobalScope
CreateEngineAndGetGlobalScope(bool fast
, String
[] assemblyNames
){
294 VsaEngine engine
= new VsaEngine(fast
);
295 engine
.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
296 engine
.doPrint
= true;
297 engine
.SetEnclosingContext(new WrappedNamespace("", engine
));
298 foreach (String assemblyName
in assemblyNames
){
299 VsaReference r
= (VsaReference
)engine
.vsaItems
.CreateItem(assemblyName
, VsaItemType
.Reference
, VsaItemFlag
.None
);
300 r
.AssemblyName
= assemblyName
;
302 VsaEngine
.exeEngine
= engine
;
303 GlobalScope scope
= (GlobalScope
)engine
.GetGlobalScope().GetObject();
304 scope
.globalObject
= engine
.Globals
.globalObject
;
308 public static GlobalScope
CreateEngineAndGetGlobalScopeWithType(bool fast
, String
[] assemblyNames
, RuntimeTypeHandle callingTypeHandle
){
309 return VsaEngine
.CreateEngineAndGetGlobalScopeWithTypeAndRootNamespace(fast
, assemblyNames
, callingTypeHandle
, null);
312 public static GlobalScope
CreateEngineAndGetGlobalScopeWithTypeAndRootNamespace(bool fast
, String
[] assemblyNames
, RuntimeTypeHandle callingTypeHandle
, string rootNamespace
){
313 VsaEngine engine
= new VsaEngine(fast
);
314 engine
.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
315 engine
.doPrint
= true;
316 engine
.SetEnclosingContext(new WrappedNamespace("", engine
));
317 if (rootNamespace
!= null)
318 engine
.SetEnclosingContext(new WrappedNamespace(rootNamespace
, engine
));
320 foreach (String assemblyName
in assemblyNames
){
321 VsaReference r
= (VsaReference
)engine
.vsaItems
.CreateItem(assemblyName
, VsaItemType
.Reference
, VsaItemFlag
.None
);
322 r
.AssemblyName
= assemblyName
;
324 // Put the engine in the CallContext so that calls to CreateEngineWithType will return this engine
325 Type callingType
= Type
.GetTypeFromHandle(callingTypeHandle
);
326 Assembly callingAssembly
= callingType
.Assembly
;
327 System
.Runtime
.Remoting
.Messaging
.CallContext
.SetData("JScript:" + callingAssembly
.FullName
, engine
);
328 // Get and return the global scope
329 GlobalScope scope
= (GlobalScope
)engine
.GetGlobalScope().GetObject();
330 scope
.globalObject
= engine
.Globals
.globalObject
;
334 private static volatile VsaEngine exeEngine
; // Instance of VsaEngine used by JScript EXEs
336 // This factory method is called by EXE code only
337 public static VsaEngine
CreateEngine(){
338 if (VsaEngine
.exeEngine
== null){
339 VsaEngine e
= new VsaEngine(true);
340 e
.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
341 VsaEngine
.exeEngine
= e
;
343 return VsaEngine
.exeEngine
;
346 internal static VsaEngine
CreateEngineForDebugger(){
347 VsaEngine engine
= new VsaEngine(true);
348 engine
.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
349 GlobalScope scope
= (GlobalScope
)engine
.GetGlobalScope().GetObject();
350 scope
.globalObject
= engine
.Globals
.globalObject
;
354 // This factory method is called by DLL code only
355 public static VsaEngine
CreateEngineWithType(RuntimeTypeHandle callingTypeHandle
){
356 Type callingType
= Type
.GetTypeFromHandle(callingTypeHandle
);
357 Assembly callingAssembly
= callingType
.Assembly
;
358 Object o
= System
.Runtime
.Remoting
.Messaging
.CallContext
.GetData("JScript:" + callingAssembly
.FullName
);
360 VsaEngine e
= o
as VsaEngine
;
365 VsaEngine engine
= new VsaEngine(callingAssembly
);
366 engine
.InitVsaEngine("JScript.Vsa.VsaEngine://Microsoft.JScript.VsaEngine.Vsa", new DefaultVsaSite());
368 GlobalScope scope
= (GlobalScope
)engine
.GetGlobalScope().GetObject();
369 scope
.globalObject
= engine
.Globals
.globalObject
;
371 // for every global class generated in this assembly make an instance and call the global code method
373 Type globalClassType
= null;
375 String globalClassName
= "JScript " + i
.ToString(CultureInfo
.InvariantCulture
);
376 globalClassType
= callingAssembly
.GetType(globalClassName
, false);
377 if (globalClassType
!= null){
378 engine
.SetEnclosingContext(new WrappedNamespace("", engine
));
379 ConstructorInfo globalScopeConstructor
= globalClassType
.GetConstructor(new Type
[]{typeof(GlobalScope)}
);
380 MethodInfo globalCode
= globalClassType
.GetMethod("Global Code");
382 Object globalClassInstance
= globalScopeConstructor
.Invoke(new Object
[]{scope}
);
383 globalCode
.Invoke(globalClassInstance
, new Object
[0]);
384 }catch(SecurityException
){
385 // [stesty] Due to bug 337909, if a JScript assembly is strongly-named but partially-trusted, it will
386 // not succeed here unless it also has the AllowPartiallyTrustedCallersAttribute. We do not
387 // want to run this constructor with elevated permissions, so we work around by abandoning
388 // the attempt, thus disabling eval in this scenario.
393 }while (globalClassType
!= null);
396 System
.Runtime
.Remoting
.Messaging
.CallContext
.SetData("JScript:" + callingAssembly
.FullName
, engine
);
400 private void AddReferences(){
401 if (VsaEngine
.assemblyReferencesTable
== null) {
403 Hashtable h
= new Hashtable();
404 VsaEngine
.assemblyReferencesTable
= Hashtable
.Synchronized(h
);
407 String
[] references
= VsaEngine
.assemblyReferencesTable
[this.runtimeAssembly
.FullName
] as String
[];
408 if (references
!= null){
409 for (int i
= 0; i
< references
.Length
; i
++){
410 VsaReference r
= (VsaReference
)this.vsaItems
.CreateItem(references
[i
], VsaItemType
.Reference
, VsaItemFlag
.None
);
411 r
.AssemblyName
= references
[i
];
414 // Read the references from the custom attribute on the assembly and create VsaReferences for each
416 Object
[] attrs
= CustomAttribute
.GetCustomAttributes(this.runtimeAssembly
, typeof(ReferenceAttribute
), false);
417 String
[] references1
= new String
[attrs
.Length
];
418 for (int i
= 0; i
< attrs
.Length
; i
++){
419 String assemblyName
= ((ReferenceAttribute
)attrs
[i
]).reference
;
420 VsaReference r
= (VsaReference
)this.vsaItems
.CreateItem(assemblyName
, VsaItemType
.Reference
, VsaItemFlag
.None
);
421 r
.AssemblyName
= assemblyName
;
422 references1
[i
] = assemblyName
;
424 VsaEngine
.assemblyReferencesTable
[this.runtimeAssembly
.FullName
] = references1
;
428 private void EmitReferences()
430 SimpleHashtable emitted
= new SimpleHashtable((uint)this.vsaItems
.Count
+ (this.implicitAssemblies
== null ? 0 : (uint)this.implicitAssemblies
.Count
));
431 foreach (Object item
in this.vsaItems
){
432 if (item
is VsaReference
){
433 String referenceName
= ((VsaReference
)item
).Assembly
.GetName().FullName
;
434 // do not write duplicate assemblies
435 if (emitted
[referenceName
] == null){
436 CustomAttributeBuilder cab
= new CustomAttributeBuilder(CompilerGlobals
.referenceAttributeConstructor
, new Object
[1] {referenceName}
);
437 this.CompilerGlobals
.assemblyBuilder
.SetCustomAttribute(cab
);
438 emitted
[referenceName
] = item
;
442 if (this.implicitAssemblies
!= null){
443 foreach (Object item
in this.implicitAssemblies
){
444 Assembly a
= item
as Assembly
;
446 String referenceName
= a
.GetName().FullName
;
447 // do not write duplicate assemblies
448 if (emitted
[referenceName
] == null){
449 CustomAttributeBuilder cab
= new CustomAttributeBuilder(CompilerGlobals
.referenceAttributeConstructor
, new Object
[1] {referenceName}
);
450 this.CompilerGlobals
.assemblyBuilder
.SetCustomAttribute(cab
);
451 emitted
[referenceName
] = item
;
458 private void CreateMain(){
459 // define a class that will hold the main method
460 TypeBuilder mainClass
= this.CompilerGlobals
.module
.DefineType("JScript Main", TypeAttributes
.Public
);
462 // create a function with the following signature void Main(String[] args)
463 MethodBuilder main
= mainClass
.DefineMethod("Main", MethodAttributes
.Public
| MethodAttributes
.Static
, Typeob
.Void
, new Type
[]{Typeob.ArrayOfString}
);
464 ILGenerator il
= main
.GetILGenerator();
466 // emit code for main method
467 this.CreateEntryPointIL(il
, null /* site */);
469 // cook method and class
470 mainClass
.CreateType();
471 // define the Main() method as the entry point for the exe
472 this.CompilerGlobals
.assemblyBuilder
.SetEntryPoint(main
, this.PEFileKind
);
475 private void CreateStartupClass(){
476 // define _Startup class for VSA (in the RootNamespace)
477 Debug
.Assert(this.rootNamespace
!= null && this.rootNamespace
.Length
> 0);
478 TypeBuilder startupClass
= this.CompilerGlobals
.module
.DefineType(this.rootNamespace
+ "._Startup", TypeAttributes
.Public
, Typeob
.BaseVsaStartup
);
479 FieldInfo site
= Typeob
.BaseVsaStartup
.GetField("site", BindingFlags
.NonPublic
| BindingFlags
.Instance
);
480 // create a function with the following signature: public virtual void Startup()
481 MethodBuilder startup
= startupClass
.DefineMethod("Startup", MethodAttributes
.Public
| MethodAttributes
.Virtual
, Typeob
.Void
, Type
.EmptyTypes
);
482 this.CreateEntryPointIL(startup
.GetILGenerator(), site
, startupClass
);
483 // create a function with the following signature: public virtual void Shutdown()
484 MethodBuilder shutdown
= startupClass
.DefineMethod("Shutdown", MethodAttributes
.Public
| MethodAttributes
.Virtual
, Typeob
.Void
, Type
.EmptyTypes
);
485 this.CreateShutdownIL(shutdown
.GetILGenerator());
487 // cook method and class
488 startupClass
.CreateType();
491 void CreateEntryPointIL(ILGenerator il
, FieldInfo site
){
492 this.CreateEntryPointIL(il
, site
, null);
495 void CreateEntryPointIL(ILGenerator il
, FieldInfo site
, TypeBuilder startupClass
){
496 LocalBuilder globalScope
= il
.DeclareLocal(Typeob
.GlobalScope
);
498 //Emit code to create an engine. We do this explicitly so that we can control fast mode.
500 il
.Emit(OpCodes
.Ldc_I4_1
);
502 il
.Emit(OpCodes
.Ldc_I4_0
);
503 //Run through the list of references and emit code to create an array of strings representing them
504 //but do not emit duplicates.
505 SimpleHashtable uniqueReferences
= new SimpleHashtable((uint)this.vsaItems
.Count
);
506 ArrayList references
= new ArrayList();
507 foreach (Object item
in this.vsaItems
){
508 if (item
is VsaReference
){
509 string assemblyName
= ((VsaReference
)item
).Assembly
.GetName().FullName
;
510 if (uniqueReferences
[assemblyName
] == null){
511 references
.Add(assemblyName
);
512 uniqueReferences
[assemblyName
] = item
;
516 if (this.implicitAssemblies
!= null){
517 foreach (Object item
in this.implicitAssemblies
){
518 Assembly a
= item
as Assembly
;
520 String assemblyName
= a
.GetName().FullName
;
521 if (uniqueReferences
[assemblyName
] == null){
522 references
.Add(assemblyName
);
523 uniqueReferences
[assemblyName
] = item
;
529 ConstantWrapper
.TranslateToILInt(il
, references
.Count
);
530 il
.Emit(OpCodes
.Newarr
, Typeob
.String
);
532 foreach (string referenceName
in references
){
533 il
.Emit(OpCodes
.Dup
);
534 ConstantWrapper
.TranslateToILInt(il
, num
++);
535 il
.Emit(OpCodes
.Ldstr
, referenceName
);
536 il
.Emit(OpCodes
.Stelem_Ref
);
538 if (startupClass
!= null){
539 il
.Emit(OpCodes
.Ldtoken
, startupClass
);
540 if (this.rootNamespace
!= null)
541 il
.Emit(OpCodes
.Ldstr
, this.rootNamespace
);
543 il
.Emit(OpCodes
.Ldnull
);
544 MethodInfo createEngineAndGetGlobalScopeWithTypeAndRootNamespace
= Typeob
.VsaEngine
.GetMethod("CreateEngineAndGetGlobalScopeWithTypeAndRootNamespace");
545 il
.Emit(OpCodes
.Call
, createEngineAndGetGlobalScopeWithTypeAndRootNamespace
);
547 MethodInfo createEngineAndGetGlobalScope
= Typeob
.VsaEngine
.GetMethod("CreateEngineAndGetGlobalScope");
548 il
.Emit(OpCodes
.Call
, createEngineAndGetGlobalScope
);
550 il
.Emit(OpCodes
.Stloc
, globalScope
);
552 // get global object instances and event source instances (CreateStartupClass scenario only)
553 if (site
!= null) this.CreateHostCallbackIL(il
, site
);
555 bool setUserEntryPoint
= this.genDebugInfo
;
557 // for every generated class make an instance and call the main routine method
559 // When there are multiple VsaStaticCode items, all members of relevance are lifted to the
560 // first one. VsaStaticCode does not munge with the runtime scope chain, and instead
561 // relies on the code here to set things up before the global code is called.
562 bool codeToSetupGlobalScopeEmitted
= false; // have we hit the first VsaStaticCode item
563 foreach (Object item
in this.vsaItems
){
564 Type compiledType
= ((VsaItem
)item
).GetCompiledType();
565 if (null != compiledType
){
566 ConstructorInfo globalScopeConstructor
= compiledType
.GetConstructor(new Type
[]{Typeob.GlobalScope}
);
567 MethodInfo globalCode
= compiledType
.GetMethod("Global Code");
568 if (setUserEntryPoint
){
569 //Set the Global Code method of the first code item to be the place where the debugger breaks for the first step into
570 this.CompilerGlobals
.module
.SetUserEntryPoint(globalCode
);
571 setUserEntryPoint
= false; //Do it once only
574 il
.Emit(OpCodes
.Ldloc
, globalScope
);
575 il
.Emit(OpCodes
.Newobj
, globalScopeConstructor
);
577 if (!codeToSetupGlobalScopeEmitted
&& item
is VsaStaticCode
) {
578 // This is the first VsaStaticCode item which holds all the relevant members.
579 // Push it onto the runtime scope stack.
580 LocalBuilder firstStaticScope
= il
.DeclareLocal(compiledType
); // all members lifted to this object
581 il
.Emit(OpCodes
.Stloc
, firstStaticScope
);
583 // Call globalScope.engine.PushScriptObject(firstStaticScope)
584 il
.Emit(OpCodes
.Ldloc
, globalScope
);
585 il
.Emit(OpCodes
.Ldfld
, CompilerGlobals
.engineField
);
586 il
.Emit(OpCodes
.Ldloc
, firstStaticScope
);
587 il
.Emit(OpCodes
.Call
, CompilerGlobals
.pushScriptObjectMethod
);
589 // Restore stack for the next Call instruction.
590 il
.Emit(OpCodes
.Ldloc
, firstStaticScope
);
591 codeToSetupGlobalScopeEmitted
= true;
594 il
.Emit(OpCodes
.Call
, globalCode
);
595 il
.Emit(OpCodes
.Pop
);
599 if (codeToSetupGlobalScopeEmitted
) {
600 // A VsaStaticCode item was encountered and code to setup the runtime
601 // stack was emitted. Restore the stack.
602 il
.Emit(OpCodes
.Ldloc
, globalScope
);
603 il
.Emit(OpCodes
.Ldfld
, CompilerGlobals
.engineField
);
604 il
.Emit(OpCodes
.Call
, CompilerGlobals
.popScriptObjectMethod
);
605 il
.Emit(OpCodes
.Pop
);
608 // a method needs a return opcode
609 il
.Emit(OpCodes
.Ret
);
612 private void CreateHostCallbackIL(ILGenerator il
, FieldInfo site
){
613 // Do callbacks to the host for global object instances
614 MethodInfo getGlobalInstance
= site
.FieldType
.GetMethod("GetGlobalInstance");
615 MethodInfo getEventSourceInstance
= site
.FieldType
.GetMethod("GetEventSourceInstance");
616 foreach (Object item
in this.vsaItems
){
617 if (item
is VsaHostObject
){
618 VsaHostObject hostObject
= (VsaHostObject
)item
;
619 // get global item instance from site
620 il
.Emit(OpCodes
.Ldarg_0
);
621 il
.Emit(OpCodes
.Ldfld
, site
);
622 il
.Emit(OpCodes
.Ldstr
, hostObject
.Name
);
623 il
.Emit(OpCodes
.Callvirt
, getGlobalInstance
);
624 // cast instance to the correct type and store into the global field
625 Type target_type
= hostObject
.Field
.FieldType
;
626 il
.Emit(OpCodes
.Ldtoken
, target_type
);
627 il
.Emit(OpCodes
.Call
, CompilerGlobals
.getTypeFromHandleMethod
);
628 ConstantWrapper
.TranslateToILInt(il
, 0);
629 il
.Emit(OpCodes
.Call
, CompilerGlobals
.coerceTMethod
);
630 if (target_type
.IsValueType
)
631 Microsoft
.JScript
.Convert
.EmitUnbox(il
, target_type
, Type
.GetTypeCode(target_type
));
633 il
.Emit(OpCodes
.Castclass
, target_type
);
634 il
.Emit(OpCodes
.Stsfld
, hostObject
.Field
);
639 private void CreateShutdownIL(ILGenerator il
){
640 // release references to global instances
641 foreach (Object item
in this.vsaItems
){
642 if (item
is VsaHostObject
){
643 il
.Emit(OpCodes
.Ldnull
);
644 il
.Emit(OpCodes
.Stsfld
, ((VsaHostObject
)item
).Field
);
647 il
.Emit(OpCodes
.Ret
);
650 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
651 public void DisconnectEvents(){
654 protected override void DoClose(){
655 ((VsaItems
)this.vsaItems
).Close();
656 if (null != this.globalScope
)
657 this.globalScope
.Close();
658 this.vsaItems
= null;
659 this.engineSite
= null;
660 this.globalScope
= null;
661 this.runningThread
= null;
662 this.compilerGlobals
= null;
664 ScriptStream
.Out
= Console
.Out
;
665 ScriptStream
.Error
= Console
.Error
;
668 this.isClosed
= true;
669 if (this.tempDirectory
!= null && Directory
.Exists(this.tempDirectory
))
670 Directory
.Delete(this.tempDirectory
);
673 protected override bool DoCompile(){
674 if (!this.isClosed
&& !this.isEngineCompiled
){
675 this.SetUpCompilerEnvironment();
676 if (this.PEFileName
== null){
677 // we use random default names to avoid overwriting cached assembly files when debugging VSA
678 this.PEFileName
= this.GenerateRandomPEFileName();
680 this.SaveSourceForDebugging(); // Save sources needed for debugging (does nothing if no debug info)
681 this.numberOfErrors
= 0; // Records number of errors during compilation.
682 this.isEngineCompiled
= true; // OnCompilerError sets to false if it encounters an unrecoverable error.
683 Globals
.ScopeStack
.Push(this.GetGlobalScope().GetObject());
686 foreach (Object item
in this.vsaItems
){
687 Debug
.Assert(item
is VsaReference
|| item
is VsaStaticCode
|| item
is VsaHostObject
);
688 if (item
is VsaReference
)
689 ((VsaReference
)item
).Compile(); //Load the assembly into memory.
691 if (this.vsaItems
.Count
> 0)
692 this.SetEnclosingContext(new WrappedNamespace("", this)); //Provide a way to find types that are not inside of a name space
693 // Add VSA global items to the global scope
694 foreach (Object item
in this.vsaItems
){
695 if (item
is VsaHostObject
)
696 ((VsaHostObject
)item
).Compile();
698 foreach (Object item
in this.vsaItems
){
699 if (item
is VsaStaticCode
)
700 ((VsaStaticCode
)item
).Parse();
702 foreach (Object item
in this.vsaItems
){
703 if (item
is VsaStaticCode
)
704 ((VsaStaticCode
)item
).ProcessAssemblyAttributeLists();
706 foreach (Object item
in this.vsaItems
){
707 if (item
is VsaStaticCode
)
708 ((VsaStaticCode
)item
).PartiallyEvaluate();
710 foreach (Object item
in this.vsaItems
){
711 if (item
is VsaStaticCode
)
712 ((VsaStaticCode
)item
).TranslateToIL();
714 foreach (Object item
in this.vsaItems
){
715 if (item
is VsaStaticCode
)
716 ((VsaStaticCode
)item
).GetCompiledType();
718 if (null != this.globalScope
)
719 this.globalScope
.Compile(); //In case the host added items to the global scope
720 }catch(JScriptException se
){
721 // It's a bit strange because we may be capturing an exception
722 // thrown by VsaEngine.OnCompilerError (in the case where
723 // this.engineSite is null. This is fine though. All we end up doing
724 // is capturing and then rethrowing the same error.
725 this.OnCompilerError(se
);
726 }catch(System
.IO
.FileLoadException e
){
727 JScriptException se
= new JScriptException(JSError
.ImplicitlyReferencedAssemblyNotFound
);
728 se
.value = e
.FileName
;
729 this.OnCompilerError(se
);
730 this.isEngineCompiled
= false;
732 // an error was reported during PartiallyEvaluate and the host decided to abort
733 // swallow the exception and keep going
735 // internal compiler error -- make sure we don't claim to have compiled, then rethrow
736 this.isEngineCompiled
= false;
740 Globals
.ScopeStack
.Pop();
742 if (this.isEngineCompiled
){
743 // there were no unrecoverable errors, but we want to return true only if there is IL
744 this.isEngineCompiled
= (this.numberOfErrors
== 0 || this.alwaysGenerateIL
);
749 if (this.managedResources
!= null){
750 foreach (ResInfo managedResource
in this.managedResources
){
751 if (managedResource
.isLinked
){
752 this.CompilerGlobals
.assemblyBuilder
.AddResourceFile(managedResource
.name
,
753 Path
.GetFileName(managedResource
.filename
),
754 managedResource
.isPublic
?
755 ResourceAttributes
.Public
:
756 ResourceAttributes
.Private
);
759 using (ResourceReader reader
= new ResourceReader(managedResource
.filename
))
761 IResourceWriter writer
= this.CompilerGlobals
.module
.DefineResource(managedResource
.name
,
762 managedResource
.filename
,
763 managedResource
.isPublic
?
764 ResourceAttributes
.Public
:
765 ResourceAttributes
.Private
);
766 foreach (DictionaryEntry resource
in reader
)
767 writer
.AddResource((string)resource
.Key
, resource
.Value
);
769 }catch(System
.ArgumentException
){
770 JScriptException se
= new JScriptException(JSError
.InvalidResource
);
771 se
.value = managedResource
.filename
;
772 this.OnCompilerError(se
);
773 this.isEngineCompiled
= false;
780 if (this.isEngineCompiled
)
781 this.EmitReferences();
783 // Save things out to a local PE file when doSaveAfterCompile is set; this is set when an
784 // output name is given (allows JSC to avoid IVsaEngine.SaveCompiledState). The proper
785 // values for VSA are doSaveAfterCompile == false and genStartupClass == true. We allow
786 // genStartupClass to be false for scenarios like JSTest and the Debugger
787 if (this.isEngineCompiled
){
788 if (this.doSaveAfterCompile
){
789 if (this.PEFileKind
!= PEFileKinds
.Dll
)
791 // After executing this code path, it is an error to call SaveCompiledState (until the engine is recompiled)
793 compilerGlobals
.assemblyBuilder
.Save(Path
.GetFileName(this.PEFileName
),
794 this.PEKindFlags
, this.PEMachineArchitecture
);
796 throw new VsaException(VsaError
.SaveCompiledStateFailed
, e
.Message
, e
);
798 throw new VsaException(VsaError
.SaveCompiledStateFailed
);
800 }else if (this.genStartupClass
){
801 // this is generated for VSA hosting
802 this.CreateStartupClass();
805 return this.isEngineCompiled
;
808 internal CultureInfo ErrorCultureInfo
{
810 if (this.errorCultureInfo
== null || this.errorCultureInfo
.LCID
!= this.errorLocale
)
811 this.errorCultureInfo
= new CultureInfo(this.errorLocale
);
812 return this.errorCultureInfo
;
816 private string GenerateRandomPEFileName(){
817 if (this.randomNumberGenerator
== null)
818 this.randomNumberGenerator
= new RNGCryptoServiceProvider();
819 // Generate random bytes
820 byte[] data
= new byte[6];
821 this.randomNumberGenerator
.GetBytes(data
);
822 // Turn them into a string containing only characters valid in file names
823 string randomString
= System
.Convert
.ToBase64String(data
);
824 randomString
= randomString
.Replace('/', '-');
825 randomString
= randomString
.Replace('+', '_');
826 // Use the first random filename as the engine's temp directory name
827 if (this.tempDirectory
== null)
828 this.tempDirectory
= System
.IO
.Path
.GetTempPath() + randomString
;
829 string filename
= randomString
+ (this.PEFileKind
== PEFileKinds
.Dll
? ".dll": ".exe");
830 return this.tempDirectory
+ Path
.DirectorySeparatorChar
+ filename
;
833 /////////////////////////////////////////////////////////////////////////////
837 /////////////////////////////////////////////////////////////////////////////
839 // [EricLi] 10 November 2001
841 // Right now the VsaEngine class requires full trust to use as
842 // an engine that runs code or generates assemblies.
844 // Preventing untrusted callers from actually compiling and
845 // running code is clearly undesirable -- we want partially-
846 // trusted host scenarios to work. For this release however
847 // there are too many poorly-understood issues involving
848 // controling the evidence property.
850 /////////////////////////////////////////////////////////////////////////////
852 [PermissionSet(SecurityAction
.Demand
, Name
="FullTrust")]
853 public Assembly
GetAssembly(){
854 this.TryObtainLock();
856 if (null != this.PEFileName
)
857 return Assembly
.LoadFrom(this.PEFileName
);
859 return compilerGlobals
.assemblyBuilder
;
865 internal ClassScope
GetClass(String className
){
866 if (this.packages
!= null)
867 for (int i
= 0, n
= this.packages
.Count
; i
< n
; i
++){
868 PackageScope pscope
= (PackageScope
)this.packages
[i
];
869 Object pval
= pscope
.GetMemberValue(className
, 1);
870 if (!(pval
is Microsoft
.JScript
.Missing
)){
871 ClassScope csc
= (ClassScope
)pval
;
878 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
879 public IVsaItem
GetItem(String itemName
){
880 return this.vsaItems
[itemName
];
883 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
884 public IVsaItem
GetItemAtIndex(int index
){
885 return this.vsaItems
[index
];
888 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
889 public int GetItemCount(){
890 return this.vsaItems
.Count
;
893 public IVsaScriptScope
GetGlobalScope(){
894 if (null == this.globalScope
){
895 this.globalScope
= new VsaScriptScope(this, "Global", null);
896 GlobalScope scope
= (GlobalScope
)this.globalScope
.GetObject();
897 scope
.globalObject
= this.Globals
.globalObject
;
898 scope
.fast
= this.doFast
;
899 scope
.isKnownAtCompileTime
= this.doFast
;
901 return this.globalScope
;
904 // Called by the debugger to get hold of the global scope from within a class method
905 public GlobalScope
GetMainScope(){
906 ScriptObject o
= ScriptObjectStackTop();
907 while (o
!= null && !(o
is GlobalScope
))
909 return (GlobalScope
)o
;
912 public Module
GetModule(){
913 if (null != this.PEFileName
){
914 Assembly a
= GetAssembly();
915 Module
[] modules
= a
.GetModules();
918 return this.CompilerGlobals
.module
;
921 public ArrayConstructor
GetOriginalArrayConstructor(){
922 return this.Globals
.globalObject
.originalArray
;
925 public ObjectConstructor
GetOriginalObjectConstructor(){
926 return this.Globals
.globalObject
.originalObject
;
929 public RegExpConstructor
GetOriginalRegExpConstructor(){
930 return this.Globals
.globalObject
.originalRegExp
;
933 protected override Object
GetCustomOption(String name
){
934 if (String
.Compare(name
, "CLSCompliant", StringComparison
.OrdinalIgnoreCase
) == 0)
935 return this.isCLSCompliant
;
936 else if (String
.Compare(name
, "fast", StringComparison
.OrdinalIgnoreCase
) == 0)
938 else if (String
.Compare(name
, "output", StringComparison
.OrdinalIgnoreCase
) == 0)
939 return this.PEFileName
;
940 else if (String
.Compare(name
, "PEFileKind", StringComparison
.OrdinalIgnoreCase
) == 0)
941 return this.PEFileKind
;
942 else if (String
.Compare(name
, "PortableExecutableKind", StringComparison
.OrdinalIgnoreCase
) == 0)
943 return this.PEKindFlags
;
944 else if (String
.Compare(name
, "ImageFileMachine", StringComparison
.OrdinalIgnoreCase
) == 0)
945 return this.PEMachineArchitecture
;
946 else if (String
.Compare(name
, "ReferenceLoaderAPI", StringComparison
.OrdinalIgnoreCase
) == 0) {
947 switch (this.ReferenceLoaderAPI
) {
948 case LoaderAPI
.LoadFrom
: return "LoadFrom";
949 case LoaderAPI
.LoadFile
: return "LoadFile";
950 case LoaderAPI
.ReflectionOnlyLoadFrom
: return "ReflectionOnlyLoadFrom";
951 default: throw new VsaException(VsaError
.OptionNotSupported
);
954 else if (String
.Compare(name
, "print", StringComparison
.OrdinalIgnoreCase
) == 0)
956 else if (String
.Compare(name
, "UseContextRelativeStatics", StringComparison
.OrdinalIgnoreCase
) == 0)
958 // the next two are needed because of the ICompiler interface. They should not fail even though they may not do anything
959 else if (String
.Compare(name
, "optimize", StringComparison
.OrdinalIgnoreCase
) == 0)
961 else if (String
.Compare(name
, "define", StringComparison
.OrdinalIgnoreCase
) == 0)
963 else if (String
.Compare(name
, "defines", StringComparison
.OrdinalIgnoreCase
) == 0)
965 else if (String
.Compare(name
, "ee", StringComparison
.OrdinalIgnoreCase
) == 0)
966 return VsaEngine
.executeForJSEE
;
967 else if (String
.Compare(name
, "version", StringComparison
.OrdinalIgnoreCase
) == 0)
968 return this.versionInfo
;
969 else if (String
.Compare(name
, "VersionSafe", StringComparison
.OrdinalIgnoreCase
) == 0)
970 return this.versionSafe
;
971 else if (String
.Compare(name
, "warnaserror", StringComparison
.OrdinalIgnoreCase
) == 0)
972 return this.doWarnAsError
;
973 else if (String
.Compare(name
, "WarningLevel", StringComparison
.OrdinalIgnoreCase
) == 0)
974 return this.nWarningLevel
;
975 else if (String
.Compare(name
, "managedResources", StringComparison
.OrdinalIgnoreCase
) == 0)
976 return this.managedResources
;
977 else if (String
.Compare(name
, "alwaysGenerateIL", StringComparison
.OrdinalIgnoreCase
) == 0)
978 return this.alwaysGenerateIL
;
979 else if (String
.Compare(name
, "DebugDirectory", StringComparison
.OrdinalIgnoreCase
) == 0)
980 return this.debugDirectory
;
981 else if (String
.Compare(name
, "AutoRef", StringComparison
.OrdinalIgnoreCase
) == 0)
984 throw new VsaException(VsaError
.OptionNotSupported
);
987 internal int GetStaticCodeBlockCount(){
988 return ((VsaItems
)this.vsaItems
).staticCodeBlockCount
;
991 internal Type
GetType(String typeName
){
992 if (this.cachedTypeLookups
== null)
993 this.cachedTypeLookups
= new SimpleHashtable(1000);
994 object cacheResult
= this.cachedTypeLookups
[typeName
];
995 if (cacheResult
== null){
996 // proceed with lookup
997 for (int i
= 0, n
= this.Scopes
.Count
; i
< n
; i
++){
998 GlobalScope scope
= (GlobalScope
)this.scopes
[i
];
999 Type result
= Globals
.TypeRefs
.ToReferenceContext(scope
.GetType()).Assembly
.GetType(typeName
, false);
1000 if (result
!= null){
1001 this.cachedTypeLookups
[typeName
] = result
;
1006 if (this.runtimeAssembly
!= null) {
1007 this.AddReferences();
1008 this.runtimeAssembly
= null;
1011 for (int i
= 0, n
= this.vsaItems
.Count
; i
< n
; i
++){
1012 object item
= this.vsaItems
[i
];
1013 if (item
is VsaReference
){
1014 Type result
= ((VsaReference
)item
).GetType(typeName
);
1015 if (result
!= null){
1016 this.cachedTypeLookups
[typeName
] = result
;
1021 if (this.implicitAssemblies
== null){
1022 this.cachedTypeLookups
[typeName
] = false;
1025 for (int i
= 0, n
= this.implicitAssemblies
.Count
; i
< n
; i
++){
1026 Assembly assembly
= (Assembly
)this.implicitAssemblies
[i
];
1027 Type result
= assembly
.GetType(typeName
, false);
1028 if (result
!= null){
1029 if (!result
.IsPublic
|| CustomAttribute
.IsDefined(result
, typeof(System
.Runtime
.CompilerServices
.RequiredAttributeAttribute
), true))
1030 result
= null; //Suppress the type if it is not public or if it is a funky C++ type.
1032 this.cachedTypeLookups
[typeName
] = result
;
1038 this.cachedTypeLookups
[typeName
] = false;
1041 return (cacheResult
as Type
);
1044 internal Globals Globals
{
1046 if (this.globals
== null)
1047 this.globals
= new Globals(this.doFast
, this);
1048 return this.globals
;
1052 internal bool HasErrors
{
1054 return this.numberOfErrors
!= 0;
1058 // GetScannerInstance is used by IsValidNamespaceName and IsValidIdentifier to validate names.
1059 // We return an instance of the scanner only if there is no whitespace in the name text, since
1060 // we do not want to allow, say, "not. valid" to be a valid namespace name even though that
1061 // would produce a valid sequence of tokens.
1062 private JSScanner
GetScannerInstance(string name
){
1063 // make sure there's no whitespace in the name (values copied from documentation on String.Trim())
1064 char[] anyWhiteSpace
= {
1065 (char)0x0009, (char)0x000A, (char)0x000B, (char)0x000C, (char)0x000D, (char)0x0020, (char)0x00A0,
1066 (char)0x2000, (char)0x2001, (char)0x2002, (char)0x2003, (char)0x2004, (char)0x2005, (char)0x2006,
1067 (char)0x2007, (char)0x2008, (char)0x2009, (char)0x200A, (char)0x200B, (char)0x3000, (char)0xFEFF
1069 if (name
== null || name
.IndexOfAny(anyWhiteSpace
) > -1)
1071 // Create a code item whose source is the given text
1072 VsaItem item
= new VsaStaticCode(this, "itemName", VsaItemFlag
.None
);
1073 Context context
= new Context(new DocumentContext(item
), name
);
1074 context
.errorReported
= -1;
1075 JSScanner scanner
= new JSScanner(); //Use this constructor to avoid allocating a Globals instance
1076 scanner
.SetSource(context
);
1080 // Use this method to initialize the engine for non-VSA use. This includes JSC, JSTest, and the JSEE.
1081 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1082 public void InitVsaEngine(string rootMoniker
, IVsaSite site
){
1083 this.genStartupClass
= false;
1084 this.engineMoniker
= rootMoniker
;
1085 this.engineSite
= site
;
1086 this.isEngineInitialized
= true;
1087 this.rootNamespace
= "JScript.DefaultNamespace";
1088 this.isEngineDirty
= true;
1089 this.isEngineCompiled
= false;
1092 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1093 public void Interrupt(){
1094 if (this.runningThread
!= null){
1095 this.runningThread
.Abort();
1096 this.runningThread
= null;
1100 protected override bool IsValidNamespaceName(string name
){
1101 JSScanner scanner
= this.GetScannerInstance(name
);
1102 if (scanner
== null)
1105 if (scanner
.PeekToken() != JSToken
.Identifier
)
1107 scanner
.GetNextToken();
1108 if (scanner
.PeekToken() == JSToken
.EndOfFile
)
1110 if (scanner
.PeekToken() != JSToken
.AccessField
)
1112 scanner
.GetNextToken();
1117 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1118 public override bool IsValidIdentifier(string ident
){
1119 JSScanner scanner
= this.GetScannerInstance(ident
);
1120 if (scanner
== null)
1122 if (scanner
.PeekToken() != JSToken
.Identifier
)
1124 scanner
.GetNextToken();
1125 if (scanner
.PeekToken() != JSToken
.EndOfFile
)
1130 public LenientGlobalObject LenientGlobalObject
{
1132 return (LenientGlobalObject
)this.Globals
.globalObject
;
1136 protected override Assembly
LoadCompiledState(){
1137 Debug
.Assert(this.haveCompiledState
);
1140 if (!this.genDebugInfo
) {
1141 System
.Security
.Policy
.Evidence compilationEvidence
= this.CompilerGlobals
.compilationEvidence
;
1142 System
.Security
.Policy
.Evidence executionEvidence
= this.executionEvidence
;
1143 if (compilationEvidence
== null && executionEvidence
== null ||
1144 compilationEvidence
!= null && compilationEvidence
.Equals(executionEvidence
))
1145 return this.compilerGlobals
.assemblyBuilder
;
1147 // we need to save/reload to properly associate debug symbols with the assembly
1148 this.DoSaveCompiledState(out pe
, out pdb
);
1149 return Assembly
.Load(pe
, pdb
, this.executionEvidence
);
1152 protected override void DoLoadSourceState(IVsaPersistSite site
){
1153 // DoSaveSourceState puts everything in the project item (use null for the name)
1154 // We assume the site is valid and contains a valid project file so any errors are
1155 // wrapped in a VsaException and thrown
1156 string projectElement
= site
.LoadElement(null);
1158 XmlDocument project
= new XmlDocument();
1159 project
.LoadXml(projectElement
);
1160 XmlElement root
= project
.DocumentElement
;
1162 // verify that we support this version of the project file
1163 if (this.LoadProjectVersion(root
) == CurrentProjectVersion
){
1164 this.LoadVsaEngineState(root
);
1165 this.isEngineDirty
= false;
1167 }catch(Exception e
){
1168 throw new VsaException(VsaError
.UnknownError
, e
.ToString(), e
);
1170 throw new VsaException(VsaError
.UnknownError
);
1174 private Version
LoadProjectVersion(XmlElement root
){
1175 return new Version(root
["ProjectVersion"].GetAttribute("Version"));
1178 private void LoadVsaEngineState(XmlElement parent
){
1179 XmlElement engine
= parent
["VsaEngine"];
1180 this.applicationPath
= engine
.GetAttribute("ApplicationBase");
1181 this.genDebugInfo
= Boolean
.Parse(engine
.GetAttribute("GenerateDebugInfo"));
1182 this.scriptLanguage
= engine
.GetAttribute("Language");
1183 this.LCID
= Int32
.Parse(engine
.GetAttribute("LCID"), CultureInfo
.InvariantCulture
);
1184 this.Name
= engine
.GetAttribute("Name");
1185 this.rootNamespace
= engine
.GetAttribute("RootNamespace");
1186 this.assemblyVersion
= engine
.GetAttribute("Version");
1187 this.LoadCustomOptions(engine
);
1188 this.LoadVsaItems(engine
);
1191 private void LoadCustomOptions(XmlElement parent
){
1192 XmlElement options
= parent
["Options"];
1193 Debug
.Assert(String
.Compare(options
.Name
, "Options", StringComparison
.OrdinalIgnoreCase
) == 0);
1194 this.doFast
= Boolean
.Parse(options
.GetAttribute("fast"));
1195 this.doPrint
= Boolean
.Parse(options
.GetAttribute("print"));
1196 this.doCRS
= Boolean
.Parse(options
.GetAttribute("UseContextRelativeStatics"));
1197 this.versionSafe
= Boolean
.Parse(options
.GetAttribute("VersionSafe"));
1198 this.libpath
= options
.GetAttribute("libpath");
1199 this.doWarnAsError
= Boolean
.Parse(options
.GetAttribute("warnaserror"));
1200 this.nWarningLevel
= Int32
.Parse(options
.GetAttribute("WarningLevel"), CultureInfo
.InvariantCulture
);
1201 this.LoadUserDefines(options
);
1202 this.LoadManagedResources(options
);
1205 private void LoadUserDefines(XmlElement parent
){
1206 XmlElement userDefines
= parent
["Defines"];
1207 XmlNodeList defines
= userDefines
.ChildNodes
;
1208 foreach (XmlElement definition
in defines
)
1209 this.Defines
[definition
.Name
] = definition
.GetAttribute("Value");
1212 private void LoadManagedResources(XmlElement parent
){
1213 XmlElement resources
= parent
["ManagedResources"];
1214 XmlNodeList managedResources
= resources
.ChildNodes
;
1215 if (managedResources
.Count
> 0){
1216 this.managedResources
= new ArrayList(managedResources
.Count
);
1217 foreach (XmlElement resource
in managedResources
){
1218 string name
= resource
.GetAttribute("Name");
1219 string filename
= resource
.GetAttribute("FileName");
1220 bool isPublic
= Boolean
.Parse(resource
.GetAttribute("Public"));
1221 bool isLinked
= Boolean
.Parse(resource
.GetAttribute("Linked"));
1222 ((ArrayList
)this.managedResources
).Add(new ResInfo(filename
, name
, isPublic
, isLinked
));
1227 private void LoadVsaItems(XmlElement parent
){
1228 XmlNodeList vsaItems
= parent
["VsaItems"].ChildNodes
;
1231 string reference
= VsaItemType
.Reference
.ToString();
1232 string appGlobal
= VsaItemType
.AppGlobal
.ToString();
1233 string code
= VsaItemType
.Code
.ToString();
1234 foreach (XmlElement vsaItem
in vsaItems
){
1235 string name
= vsaItem
.GetAttribute("Name");
1236 itemType
= vsaItem
.GetAttribute("ItemType");
1237 if (String
.Compare(itemType
, reference
, StringComparison
.OrdinalIgnoreCase
) == 0){
1238 item
= this.vsaItems
.CreateItem(name
, VsaItemType
.Reference
, VsaItemFlag
.None
);
1239 ((IVsaReferenceItem
)item
).AssemblyName
= vsaItem
.GetAttribute("AssemblyName");
1240 }else if (String
.Compare(itemType
, appGlobal
, StringComparison
.OrdinalIgnoreCase
) == 0){
1241 item
= this.vsaItems
.CreateItem(name
, VsaItemType
.AppGlobal
, VsaItemFlag
.None
);
1242 ((IVsaGlobalItem
)item
).ExposeMembers
= Boolean
.Parse(vsaItem
.GetAttribute("ExposeMembers"));
1243 ((IVsaGlobalItem
)item
).TypeString
= vsaItem
.GetAttribute("TypeString");
1244 }else if (String
.Compare(itemType
, code
, StringComparison
.OrdinalIgnoreCase
) == 0){
1245 item
= this.vsaItems
.CreateItem(name
, VsaItemType
.Code
, VsaItemFlag
.None
);
1246 XmlCDataSection sourceText
= (XmlCDataSection
)vsaItem
.FirstChild
;
1247 string unescapedText
= sourceText
.Value
.Replace(" >", ">");
1248 ((IVsaCodeItem
)item
).SourceText
= unescapedText
;
1250 throw new VsaException(VsaError
.LoadElementFailed
);
1251 XmlNodeList vsaItemOptions
= vsaItem
["Options"].ChildNodes
;
1252 foreach (XmlElement option
in vsaItemOptions
){
1253 item
.SetOption(option
.Name
, option
.GetAttribute("Value"));
1255 ((VsaItem
)item
).IsDirty
= false;
1259 internal bool OnCompilerError(JScriptException se
){
1260 if (se
.Severity
== 0 || (this.doWarnAsError
&& se
.Severity
<= this.nWarningLevel
))
1261 this.numberOfErrors
++;
1262 bool canRecover
= this.engineSite
.OnCompilerError(se
); //true means carry on with compilation.
1264 this.isEngineCompiled
= false;
1268 public ScriptObject
PopScriptObject(){
1269 return (ScriptObject
)this.Globals
.ScopeStack
.Pop();
1272 public void PushScriptObject(ScriptObject obj
){
1273 this.Globals
.ScopeStack
.Push(obj
);
1276 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1277 public void RegisterEventSource(String name
){
1280 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1281 public override void Reset(){
1282 if (this.genStartupClass
)
1285 this.ResetCompiledState();
1288 protected override void ResetCompiledState(){
1289 if (this.globalScope
!= null){
1290 this.globalScope
.Reset();
1291 this.globalScope
= null;
1293 this.classCounter
= 0;
1294 this.haveCompiledState
= false;
1295 this.failedCompilation
= true;
1296 this.compiledRootNamespace
= null;
1297 this.startupClass
= null;
1298 this.compilerGlobals
= null;
1299 this.globals
= null;
1300 foreach (Object item
in this.vsaItems
)
1301 ((VsaItem
)item
).Reset();
1302 this.implicitAssemblies
= null;
1303 this.implicitAssemblyCache
= null;
1304 this.cachedTypeLookups
= null;
1305 this.isEngineCompiled
= false;
1306 this.isEngineRunning
= false;
1307 this.isCompilerSet
= false;
1308 this.packages
= null;
1309 if (!this.doSaveAfterCompile
)
1310 this.PEFileName
= null;
1315 // the debugger restart the engine to run different expression evaluation
1316 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1317 public void Restart(){
1318 this.TryObtainLock();
1320 ((VsaItems
)this.vsaItems
).Close();
1321 if (null != this.globalScope
)
1322 this.globalScope
.Close();
1323 this.globalScope
= null;
1324 this.vsaItems
= new VsaItems(this);
1325 this.isEngineRunning
= false;
1326 this.isEngineCompiled
= false;
1327 this.isCompilerSet
= false;
1328 this.isClosed
= false;
1329 this.runningThread
= null;
1330 this.globals
= null;
1336 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1337 public void RunEmpty(){
1338 this.TryObtainLock();
1340 Preconditions(Pre
.EngineNotClosed
| Pre
.RootMonikerSet
| Pre
.SiteSet
);
1341 this.isEngineRunning
= true;
1342 // save the current thread so it can be interrupted
1343 this.runningThread
= Thread
.CurrentThread
;
1344 if (null != this.globalScope
)
1345 this.globalScope
.Run();
1346 foreach (Object item
in this.vsaItems
)
1347 ((VsaItem
)item
).Run();
1349 this.runningThread
= null;
1354 [PermissionSetAttribute(SecurityAction
.LinkDemand
, Name
= "FullTrust")]
1355 public void Run(AppDomain domain
){
1356 // managed engines are not supporting Run in user-provided AppDomains
1357 throw new System
.NotImplementedException();
1360 protected override void DoSaveCompiledState(out byte[] pe
, out byte[] pdb
){
1363 if (this.rawPE
== null){
1365 // Save things out to a local PE file, then read back into memory
1366 // PEFileName was set in the Compile method and we must have compiled in order to be calling this
1367 if (!Directory
.Exists(this.tempDirectory
))
1368 Directory
.CreateDirectory(this.tempDirectory
);
1369 this.compilerGlobals
.assemblyBuilder
.Save(Path
.GetFileName(this.PEFileName
),
1370 this.PEKindFlags
, this.PEMachineArchitecture
);
1371 string tempPDBName
= Path
.ChangeExtension(this.PEFileName
, ".ildb");
1373 FileStream stream
= new FileStream(this.PEFileName
, FileMode
.Open
, FileAccess
.Read
, FileShare
.Read
);
1375 this.rawPE
= new byte[(int)stream
.Length
];
1376 stream
.Read(this.rawPE
, 0, this.rawPE
.Length
);
1380 // genDebugInfo could have been changed since we compiled, so check to make sure the symbols are there
1381 if (File
.Exists(tempPDBName
)){
1382 stream
= new FileStream(tempPDBName
, FileMode
.Open
, FileAccess
.Read
, FileShare
.Read
);
1384 this.rawPDB
= new byte[(int)stream
.Length
];
1385 stream
.Read(this.rawPDB
, 0, this.rawPDB
.Length
);
1391 File
.Delete(this.PEFileName
);
1392 if (File
.Exists(tempPDBName
))
1393 File
.Delete(tempPDBName
);
1395 }catch(Exception e
){
1396 throw new VsaException(VsaError
.SaveCompiledStateFailed
, e
.ToString(), e
);
1398 throw new VsaException(VsaError
.SaveCompiledStateFailed
);
1405 protected override void DoSaveSourceState(IVsaPersistSite site
){
1406 XmlDocument project
= new XmlDocument();
1407 project
.LoadXml("<project></project>");
1408 XmlElement root
= project
.DocumentElement
;
1409 this.SaveProjectVersion(project
, root
);
1410 this.SaveVsaEngineState(project
, root
);
1411 site
.SaveElement(null, project
.OuterXml
);
1412 this.SaveSourceForDebugging();
1413 this.isEngineDirty
= false;
1416 private void SaveSourceForDebugging(){
1417 if (!this.GenerateDebugInfo
|| this.debugDirectory
== null || !this.isEngineDirty
)
1419 foreach (VsaItem item
in this.vsaItems
){
1420 if (item
is VsaStaticCode
){
1421 string fileName
= this.debugDirectory
+ item
.Name
+ ".js";
1423 using (FileStream file
= new FileStream(fileName
, FileMode
.Create
, FileAccess
.Write
)) {
1424 using (StreamWriter sw
= new StreamWriter(file
))
1425 sw
.Write(((VsaStaticCode
)item
).SourceText
);
1426 item
.SetOption("codebase", fileName
);
1429 // swallow any file creation exceptions
1435 private void SaveProjectVersion(XmlDocument project
, XmlElement root
){
1436 XmlElement version
= project
.CreateElement("ProjectVersion");
1437 this.CreateAttribute(project
, version
, "Version", CurrentProjectVersion
.ToString());
1438 root
.AppendChild(version
);
1441 private void SaveVsaEngineState(XmlDocument project
, XmlElement parent
){
1442 XmlElement engine
= project
.CreateElement("VsaEngine");
1443 // add IVsaEngine properties as attributes
1444 this.CreateAttribute(project
, engine
, "ApplicationBase", this.applicationPath
);
1445 this.CreateAttribute(project
, engine
, "GenerateDebugInfo", this.genDebugInfo
.ToString());
1446 this.CreateAttribute(project
, engine
, "Language", this.scriptLanguage
);
1447 this.CreateAttribute(project
, engine
, "LCID", this.errorLocale
.ToString(CultureInfo
.InvariantCulture
));
1448 this.CreateAttribute(project
, engine
, "Name", this.engineName
);
1449 this.CreateAttribute(project
, engine
, "RootNamespace", this.rootNamespace
);
1450 this.CreateAttribute(project
, engine
, "Version", this.assemblyVersion
);
1451 this.SaveCustomOptions(project
, engine
);
1452 this.SaveVsaItems(project
, engine
);
1453 parent
.AppendChild(engine
);
1456 private void SaveCustomOptions(XmlDocument project
, XmlElement parent
){
1457 XmlElement options
= project
.CreateElement("Options");
1458 this.CreateAttribute(project
, options
, "fast", this.doFast
.ToString());
1459 this.CreateAttribute(project
, options
, "print", this.doPrint
.ToString());
1460 this.CreateAttribute(project
, options
, "UseContextRelativeStatics", this.doCRS
.ToString());
1461 this.CreateAttribute(project
, options
, "VersionSafe", this.versionSafe
.ToString());
1462 this.CreateAttribute(project
, options
, "libpath", this.libpath
);
1463 this.CreateAttribute(project
, options
, "warnaserror", this.doWarnAsError
.ToString());
1464 this.CreateAttribute(project
, options
, "WarningLevel", this.nWarningLevel
.ToString(CultureInfo
.InvariantCulture
));
1465 this.SaveUserDefines(project
, options
);
1466 this.SaveManagedResources(project
, options
);
1467 parent
.AppendChild(options
);
1470 private void SaveUserDefines(XmlDocument project
, XmlElement parent
){
1471 XmlElement userDefines
= project
.CreateElement("Defines");
1472 if (this.Defines
!= null){
1473 foreach (string key
in this.Defines
.Keys
){
1474 this.AddChildAndValue(project
, userDefines
, key
, (string)this.Defines
[key
]);
1477 parent
.AppendChild(userDefines
);
1480 private void SaveManagedResources(XmlDocument project
, XmlElement parent
){
1481 // Save managed resources
1482 XmlElement managedResources
= project
.CreateElement("ManagedResources");
1483 if (this.managedResources
!= null){
1484 foreach (ResInfo resinfo
in this.managedResources
){
1485 XmlElement resource
= project
.CreateElement(resinfo
.name
);
1486 this.CreateAttribute(project
, resource
, "File", resinfo
.filename
);
1487 this.CreateAttribute(project
, resource
, "Public", resinfo
.isPublic
.ToString());
1488 this.CreateAttribute(project
, resource
, "Linked", resinfo
.isLinked
.ToString());
1489 managedResources
.AppendChild(resource
);
1492 parent
.AppendChild(managedResources
);
1495 private void SaveVsaItems(XmlDocument project
, XmlElement parent
){
1496 XmlElement vsaItems
= project
.CreateElement("VsaItems");
1497 foreach (IVsaItem item
in this.vsaItems
){
1498 XmlElement vsaItem
= project
.CreateElement("IVsaItem");
1499 this.CreateAttribute(project
, vsaItem
, "Name", item
.Name
);
1500 this.CreateAttribute(project
, vsaItem
, "ItemType", item
.ItemType
.ToString(CultureInfo
.InvariantCulture
));
1501 XmlElement vsaItemOptions
= project
.CreateElement("Options");
1502 if (item
is VsaHostObject
){
1503 // VsaItemType.AppGlobal
1504 this.CreateAttribute(project
, vsaItem
, "TypeString", ((VsaHostObject
)item
).TypeString
);
1505 this.CreateAttribute(project
, vsaItem
, "ExposeMembers", ((VsaHostObject
)item
).ExposeMembers
.ToString(CultureInfo
.InvariantCulture
));
1506 }else if (item
is VsaReference
){
1507 // VsaItemType.Reference
1508 CreateAttribute(project
, vsaItem
, "AssemblyName", ((VsaReference
)item
).AssemblyName
);
1509 }else if (item
is VsaStaticCode
){
1511 string escapedText
= ((VsaStaticCode
)item
).SourceText
.Replace(">", " >");
1512 XmlCDataSection source
= project
.CreateCDataSection(escapedText
);
1513 vsaItem
.AppendChild(source
);
1514 string codebase
= (string)item
.GetOption("codebase");
1515 if (codebase
!= null)
1516 this.AddChildAndValue(project
, vsaItemOptions
, "codebase", codebase
);
1518 throw new VsaException(VsaError
.SaveElementFailed
);
1519 ((VsaItem
)item
).IsDirty
= false;
1520 vsaItem
.AppendChild(vsaItemOptions
);
1521 vsaItems
.AppendChild(vsaItem
);
1523 parent
.AppendChild(vsaItems
);
1526 internal ArrayList Scopes
{
1528 if (this.scopes
== null)
1529 this.scopes
= new ArrayList(8);
1534 public ScriptObject
ScriptObjectStackTop(){
1535 return (ScriptObject
)this.Globals
.ScopeStack
.Peek();
1538 internal void SetEnclosingContext(ScriptObject ob
){
1539 ScriptObject s
= this.Globals
.ScopeStack
.Peek();
1540 while (s
.GetParent() != null)
1545 public void SetOutputStream(IMessageReceiver output
){
1546 COMCharStream stream
= new COMCharStream(output
);
1547 System
.IO
.StreamWriter writer
= new System
.IO
.StreamWriter(stream
, Encoding
.Default
);
1548 writer
.AutoFlush
= true;
1549 ScriptStream
.Out
= writer
;
1550 ScriptStream
.Error
= writer
;
1553 protected override void SetCustomOption(String name
, Object
value){
1555 if (String
.Compare(name
, "CLSCompliant", StringComparison
.OrdinalIgnoreCase
) == 0)
1556 this.isCLSCompliant
= (bool)value;
1557 else if (String
.Compare(name
, "fast", StringComparison
.OrdinalIgnoreCase
) == 0)
1558 this.doFast
= (bool)value;
1559 else if (String
.Compare(name
, "output", StringComparison
.OrdinalIgnoreCase
) == 0){
1560 if (value is String
){
1561 this.PEFileName
= (String
)value;
1562 this.doSaveAfterCompile
= true;
1564 }else if (String
.Compare(name
, "PEFileKind", StringComparison
.OrdinalIgnoreCase
) == 0)
1565 this.PEFileKind
= (PEFileKinds
)value;
1566 else if (String
.Compare(name
, "PortableExecutableKind", StringComparison
.OrdinalIgnoreCase
) == 0)
1567 this.PEKindFlags
= (PortableExecutableKinds
)value;
1568 else if (String
.Compare(name
, "ImageFileMachine", StringComparison
.OrdinalIgnoreCase
) == 0)
1569 this.PEMachineArchitecture
= (ImageFileMachine
)value;
1570 else if (String
.Compare(name
, "ReferenceLoaderAPI", StringComparison
.OrdinalIgnoreCase
) == 0) {
1571 String loaderAPI
= (string)value;
1572 if (String
.Compare(loaderAPI
, "LoadFrom", StringComparison
.OrdinalIgnoreCase
) == 0)
1573 this.ReferenceLoaderAPI
= LoaderAPI
.LoadFrom
;
1574 else if (String
.Compare(loaderAPI
, "LoadFile", StringComparison
.OrdinalIgnoreCase
) == 0)
1575 this.ReferenceLoaderAPI
= LoaderAPI
.LoadFile
;
1576 else if (String
.Compare(loaderAPI
, "ReflectionOnlyLoadFrom", StringComparison
.OrdinalIgnoreCase
) == 0)
1577 this.ReferenceLoaderAPI
= LoaderAPI
.ReflectionOnlyLoadFrom
;
1579 throw new VsaException(VsaError
.OptionInvalid
);
1581 else if (String
.Compare(name
, "print", StringComparison
.OrdinalIgnoreCase
) == 0)
1582 this.doPrint
= (bool)value;
1583 else if (String
.Compare(name
, "UseContextRelativeStatics", StringComparison
.OrdinalIgnoreCase
) == 0)
1584 this.doCRS
= (bool)value;
1585 // the next two are needed because of the ICompiler interface. They should not fail even though they may not do anything
1586 else if (String
.Compare(name
, "optimize", StringComparison
.OrdinalIgnoreCase
) == 0)
1588 else if (String
.Compare(name
, "define", StringComparison
.OrdinalIgnoreCase
) == 0)
1590 else if (String
.Compare(name
, "defines", StringComparison
.OrdinalIgnoreCase
) == 0)
1591 this.Defines
= (Hashtable
)value;
1592 else if (String
.Compare(name
, "ee", StringComparison
.OrdinalIgnoreCase
) == 0)
1593 VsaEngine
.executeForJSEE
= (Boolean
)value;
1594 else if (String
.Compare(name
, "version", StringComparison
.OrdinalIgnoreCase
) == 0)
1595 this.versionInfo
= (Version
)value;
1596 else if (String
.Compare(name
, "VersionSafe", StringComparison
.OrdinalIgnoreCase
) == 0)
1597 this.versionSafe
= (Boolean
)value;
1598 else if (String
.Compare(name
, "libpath", StringComparison
.OrdinalIgnoreCase
) == 0)
1599 this.libpath
= (String
)value;
1600 else if (String
.Compare(name
, "warnaserror", StringComparison
.OrdinalIgnoreCase
) == 0)
1601 this.doWarnAsError
= (bool)value;
1602 else if (String
.Compare(name
, "WarningLevel", StringComparison
.OrdinalIgnoreCase
) == 0)
1603 this.nWarningLevel
= (int)value;
1604 else if (String
.Compare(name
, "managedResources", StringComparison
.OrdinalIgnoreCase
) == 0)
1605 this.managedResources
= (ICollection
)value;
1606 else if (String
.Compare(name
, "alwaysGenerateIL", StringComparison
.OrdinalIgnoreCase
) == 0)
1607 this.alwaysGenerateIL
= (bool)value;
1608 else if (String
.Compare(name
, "DebugDirectory", StringComparison
.OrdinalIgnoreCase
) == 0){
1609 // use null to turn off SaveSourceState source generation
1611 this.debugDirectory
= null;
1614 string dir
= value as string;
1616 throw new VsaException(VsaError
.OptionInvalid
);
1618 dir
= Path
.GetFullPath(dir
+ Path
.DirectorySeparatorChar
);
1619 if (!Directory
.Exists(dir
))
1620 Directory
.CreateDirectory(dir
);
1621 }catch(Exception e
){
1622 // we couldn't create the specified directory
1623 throw new VsaException(VsaError
.OptionInvalid
, "", e
);
1625 // we couldn't create the specified directory
1626 throw new VsaException(VsaError
.OptionInvalid
);
1628 this.debugDirectory
= dir
;
1629 }else if (String
.Compare(name
, "AutoRef", StringComparison
.OrdinalIgnoreCase
) == 0)
1630 this.autoRef
= (bool)value;
1632 throw new VsaException(VsaError
.OptionNotSupported
);
1633 }catch(VsaException
){
1636 throw new VsaException(VsaError
.OptionInvalid
);
1640 internal void SetUpCompilerEnvironment(){
1641 if (!this.isCompilerSet
){
1642 Microsoft
.JScript
.Globals
.TypeRefs
= this.TypeRefs
;
1643 this.globals
= this.Globals
;
1644 this.isCompilerSet
= true;
1648 internal void TryToAddImplicitAssemblyReference(String name
){
1649 if (!this.autoRef
) return;
1652 SimpleHashtable implictAssemblyCache
= this.implicitAssemblyCache
;
1653 if (implicitAssemblyCache
== null) {
1654 //Populate cache with things that should not be autoref'd. Canonical form is lower case without extension.
1655 implicitAssemblyCache
= new SimpleHashtable(50);
1657 //PEFileName always includes an extension and is never NULL.
1658 implicitAssemblyCache
[Path
.GetFileNameWithoutExtension(this.PEFileName
).ToLowerInvariant()] = true;
1660 foreach (Object item
in this.vsaItems
){
1661 VsaReference assemblyReference
= item
as VsaReference
;
1662 if (assemblyReference
== null || assemblyReference
.AssemblyName
== null) continue;
1663 key
= Path
.GetFileName(assemblyReference
.AssemblyName
).ToLowerInvariant();
1664 if (key
.EndsWith(".dll", StringComparison
.Ordinal
))
1665 key
= key
.Substring(0, key
.Length
-4);
1666 implicitAssemblyCache
[key
] = true;
1668 this.implicitAssemblyCache
= implicitAssemblyCache
;
1671 key
= name
.ToLowerInvariant();
1672 if (implicitAssemblyCache
[key
] != null) return;
1673 implicitAssemblyCache
[key
] = true;
1676 VsaReference assemblyReference
= new VsaReference(this, name
+ ".dll");
1677 if (assemblyReference
.Compile(false)){
1678 ArrayList implicitAssemblies
= this.implicitAssemblies
;
1679 if (implicitAssemblies
== null) {
1680 implicitAssemblies
= new ArrayList();
1681 this.implicitAssemblies
= implicitAssemblies
;
1683 implicitAssemblies
.Add(assemblyReference
.Assembly
);
1685 }catch(VsaException
){
1689 internal String RuntimeDirectory
{
1691 if (this.runtimeDirectory
== null){
1692 //Get the path to mscorlib.dll
1693 String s
= typeof(Object
).Module
.FullyQualifiedName
;
1694 //Remove the file part to get the directory
1695 this.runtimeDirectory
= Path
.GetDirectoryName(s
);
1697 return this.runtimeDirectory
;
1701 internal String
[] LibpathList
{
1703 if (this.libpathList
== null){
1704 if (this.libpath
== null)
1705 this.libpathList
= new String
[]{typeof(Object).Module.Assembly.Location}
;
1707 this.libpathList
= this.libpath
.Split(new Char
[] {Path.PathSeparator}
);
1709 return this.libpathList
;
1713 internal String
FindAssembly(String name
){
1715 if (Path
.GetFileName(name
) == name
){ // just the filename, no path
1716 // Look in current directory
1717 if (File
.Exists(name
))
1718 path
= Directory
.GetCurrentDirectory() + Path
.DirectorySeparatorChar
+ name
;
1720 // Look in COM+ runtime directory
1721 String path1
= this.RuntimeDirectory
+ Path
.DirectorySeparatorChar
+ name
;
1722 if (File
.Exists(path1
))
1725 // Look on the LIBPATH
1726 String
[] libpathList
= this.LibpathList
;
1727 foreach( String l
in libpathList
){
1729 path1
= l
+ Path
.DirectorySeparatorChar
+ name
;
1730 if (File
.Exists(path1
)){
1739 if (!File
.Exists(path
))
1744 protected override void ValidateRootMoniker(string rootMoniker
){
1745 // We override this method to avoid reading the registry in a non-VSA scenario
1746 if (this.genStartupClass
)
1747 base.ValidateRootMoniker(rootMoniker
);
1748 else if (rootMoniker
== null || rootMoniker
.Length
== 0)
1749 throw new VsaException(VsaError
.RootMonikerInvalid
);
1752 internal static bool CheckIdentifierForCLSCompliance(String name
){
1755 for (int i
= 0; i
< name
.Length
; i
++){
1762 internal void CheckTypeNameForCLSCompliance(String name
, String fullname
, Context context
){
1763 if (!this.isCLSCompliant
)
1765 if (name
[0] == '_'){
1766 context
.HandleError(JSError
.NonCLSCompliantType
);
1769 if (!VsaEngine
.CheckIdentifierForCLSCompliance(fullname
)){
1770 context
.HandleError(JSError
.NonCLSCompliantType
);
1773 if (this.typenameTable
== null)
1774 this.typenameTable
= new Hashtable(StringComparer
.OrdinalIgnoreCase
);
1775 if (this.typenameTable
[fullname
] == null)
1776 this.typenameTable
[fullname
] = fullname
;
1778 context
.HandleError(JSError
.NonCLSCompliantType
);
1783 // The VSA spec requires that every IVsaEngine has a host property that is non-null.
1784 // Since every assembly that we generate creates an engine (see CreateEngineAndGetGlobalScope)
1785 // we must provide a default site for it.
1787 class DefaultVsaSite
: BaseVsaSite
{
1788 public override bool OnCompilerError(IVsaError error
){
1789 // We expect only JScriptExceptions here, and we throw them to be caught by the host
1790 throw (JScriptException
)error
;